Added a 'state' field to the xenbus_device structure, which caches the state
authoremellor@leeni.uk.xensource.com <emellor@leeni.uk.xensource.com>
Sat, 4 Mar 2006 18:10:56 +0000 (19:10 +0100)
committeremellor@leeni.uk.xensource.com <emellor@leeni.uk.xensource.com>
Sat, 4 Mar 2006 18:10:56 +0000 (19:10 +0100)
at the local end of the xenbus connection (i.e. that value that is passed
through xenbus_switch_state).  This means that xenbus_probe can wait for all
the boot devices to become ready without having to hurt the store.

Also, fix this probing -- previously, the wrong value was being returned by
all_devices_ready_, so this polling would only have waited for one device.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
linux-2.6-xen-sparse/include/xen/xenbus.h

index 444f0e9f0da36a26b33f2fea2d2c1190fad82226..d8d0b9e71d209f779606df7958c495b196f22995 100644 (file)
@@ -95,18 +95,25 @@ int xenbus_switch_state(struct xenbus_device *dev,
         */
 
        int current_state;
+       int err;
+
+       if (state == dev->state)
+               return 0;
 
-       int err = xenbus_scanf(xbt, dev->nodename, "state", "%d",
+       err = xenbus_scanf(xbt, dev->nodename, "state", "%d",
                               &current_state);
-       if ((err == 1 && (XenbusState)current_state == state) ||
-           err == -ENOENT)
+       if (err != 1)
                return 0;
 
        err = xenbus_printf(xbt, dev->nodename, "state", "%d", state);
        if (err) {
-               xenbus_dev_fatal(dev, err, "writing new state");
+               if (state != XenbusStateClosing) /* Avoid looping */
+                       xenbus_dev_fatal(dev, err, "writing new state");
                return err;
        }
+
+       dev->state = state;
+
        return 0;
 }
 EXPORT_SYMBOL(xenbus_switch_state);
@@ -138,7 +145,6 @@ void _dev_error(struct xenbus_device *dev, int err, const char *fmt,
        ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
 
        BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
-       dev->has_error = 1;
 
        dev_err(&dev->dev, "%s\n", printf_buffer);
 
index cab6d5bec8e34fd5f5853c18ef397c57d91b948b..1bf9e549085360dae51c0fa87060d5b4540375d1 100644 (file)
@@ -888,16 +888,13 @@ static int all_devices_ready_(struct device *dev, void *data)
 {
        struct xenbus_device *xendev = to_xenbus_device(dev);
        int *result = data;
-       int state;
 
-       int err = xenbus_scanf(XBT_NULL, xendev->nodename, "state", "%d",
-                              &state);
-       if (err != 1 || state != XenbusStateConnected) {
+       if (xendev->state != XenbusStateConnected) {
                result = 0;
                return 1;
        }
 
-       return 1;
+       return 0;
 }
 
 
index 88b7420935037dd7553f63054f63447c17b8c593..5c1507b8b087ad6bb05d78c9650c445b5eea5565 100644 (file)
@@ -63,7 +63,7 @@ struct xenbus_device {
        int otherend_id;
        struct xenbus_watch otherend_watch;
        struct device dev;
-       int has_error;
+       XenbusState state;
        void *data;
 };